<template>
<div class="users">
  <!-- 面包屑导航 -->
  <el-breadcrumb separator-class="el-icon-arrow-right">
    <el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
    <el-breadcrumb-item>用户管理</el-breadcrumb-item>
    <el-breadcrumb-item>用户列表</el-breadcrumb-item>
  </el-breadcrumb>
  <el-card class="box-card">
    <!-- 输入框和按钮 -->
    <el-row :gutter="20">
      <!-- 搜索框 -->
      <el-col :span="8">
        <el-input placeholder="请输入用户名" clearable v-model="queryInfo.query" @clear="getUsers">
          <el-button slot="append" icon="el-icon-search" @click="getUsers"></el-button>
        </el-input>
      </el-col>
      <!-- 添加用户 -->
      <el-col :span="4">
        <el-button type="primary" @click="isAddDialogShow = true">添加用户</el-button>
      </el-col>
    </el-row>
    <!-- 展示用户列表 -->
    <el-table :data="userList" border style="width: 100%">
      <!-- 自动添加索引列 -->
      <el-table-column type="index"></el-table-column>
      <el-table-column prop="username" label="用户名"></el-table-column>
      <el-table-column prop="mobile" label="联系方式"></el-table-column>
      <el-table-column prop="email" label="邮箱"></el-table-column>
      <el-table-column prop="role_name" label="角色"></el-table-column>
      <el-table-column label="状态">
        <!-- 利用作用域插槽获取当前列数据 scope.row -->
        <template slot-scope="scope">
          <!-- 状态开关按钮 -->
          <el-switch v-model="scope.row.mg_state" @change="userStausChange(scope.row)"></el-switch>
        </template>
      </el-table-column>
      <!-- 操作按钮 -->
      <el-table-column label="操作" width="180px">
        <template slot-scope="scope">
          <!-- 编辑按钮 -->
          <el-button type="primary" icon="el-icon-edit" size="mini" @click="showChangeUserDialog(scope.row.id)"></el-button>
          <!-- 删除按钮 -->
          <el-button type="danger" icon="el-icon-delete" size="mini" @click="delectUser(scope.row.id)"></el-button>
          <!-- 修改角色按钮上浮提示框 -->
          <el-tooltip effect="dark" content="修改角色" placement="top" :enterable="false">
            <!-- 修改角色按钮 -->
            <el-button type="warning" icon="el-icon-setting" size="mini" @click="editUserRole(scope.row)"></el-button>
          </el-tooltip>
        </template>
      </el-table-column>
    </el-table>
    <!-- 分页部分 -->
    <el-pagination @size-change="pageSizeChange" @current-change="pageCurrentChange" :current-page="queryInfo.pagenum" :page-sizes="[1, 2, 3, 5]" :page-size="queryInfo.pagesize" layout="total, sizes, prev, pager, next, jumper" :total="total">
    </el-pagination>
  </el-card>

  <!-- 添加用户对话框模块 -->
  <el-dialog title="添加用户" :visible.sync="isAddDialogShow" width="50%" @close="resetAddFrom">
    <!-- 主体区域 -->
    <!-- 表单数据模块 -->
    <el-form :model="addUserInfo" :rules="UserRules" ref="addUserRulesRef" label-width="80px" >
      <!-- 填写用户名你 -->
      <el-form-item label="用户名" prop="username">
        <el-input v-model="addUserInfo.username"></el-input>
      </el-form-item>
      <!-- 填写密码 -->
      <el-form-item label="密码" prop="password">
        <el-input v-model="addUserInfo.password"></el-input>
      </el-form-item>
      <!-- 填写邮箱 -->
      <el-form-item label="邮箱" prop="email">
        <el-input v-model="addUserInfo.email"></el-input>
      </el-form-item>
      <!-- 填写手机号 -->
      <el-form-item label="手机号" prop="mobile">
        <el-input v-model="addUserInfo.mobile"></el-input>
      </el-form-item>
    </el-form>
    <!-- 底部按钮 -->
    <span slot="footer" class="dialog-footer">
      <!-- 取消按钮 -->
      <el-button @click="isAddDialogShow = false">取 消</el-button>
      <!-- 确定按钮 -->
      <el-button type="primary" @click="addUser">确 定</el-button>
    </span>
  </el-dialog>

  <!-- 修改用户对话框 -->
  <el-dialog title="修改用户信息" :visible.sync="isChangeDialogShow" width="50%" @close="resetChangeFrom">
    <!-- 修改用户表单 -->
    <!-- 表单数据模块 -->
    <el-form :model="changeUserInfo" :rules="UserRules" ref="changeUserRef" label-width="80px" >
      <!-- 显示用户名你 -->
      <el-form-item label="用户名">
        <el-input v-model="changeUserInfo.username" disabled></el-input>
      </el-form-item>
      <!-- 修改邮箱 -->
      <el-form-item label="邮箱" prop="email">
        <el-input v-model="changeUserInfo.email"></el-input>
      </el-form-item>
      <!-- 修改手机号 -->
      <el-form-item label="手机号" prop="mobile">
        <el-input v-model="changeUserInfo.mobile"></el-input>
      </el-form-item>
    </el-form>
    <span slot="footer" class="dialog-footer">
      <el-button @click="isChangeDialogShow = false">取 消</el-button>
      <el-button type="primary" @click="changeUser(changeUserInfo.id)">确 定</el-button>
    </span>
  </el-dialog>

  <!-- 修改角色对话框 -->
  <el-dialog title="修改角色" width="50%" :visible.sync="isShowEditRoleDialogVisible" @close="closeEditRoleDialog">
    <el-form tabel-width="80px" >
      <div>
        <p>当前用户：{{onEditUserRoleInfo.username}}</p>
        <p>当前角色：{{onEditUserRoleInfo.role_name}}</p>
      </div>
      <el-form-item label="角色列表">
        <el-select v-model="updateRole" :placeholder="onEditUserRoleInfo.role_name">
          <el-option v-for="item in roleInfo" :key="item.id" :label="item.roleName" :value="item.id">
          </el-option>
        </el-select>
      </el-form-item>
    </el-form>
    <span slot="footer" class="dialog-footer">
      <el-button @click="isShowEditRoleDialogVisible = false">取 消</el-button>
      <el-button type="primary" @click="updateUserRole">确 定</el-button>
    </span>
  </el-dialog>
</div>
</template>

<script>
export default {
  data() {
    // 定义邮箱的验证规则 验证邮箱是否合法
    const checkEmail = (rule, value, cb) => {
      // 邮箱的正则
      const regEmail = /^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/
      // 验收邮箱的合法性
      if (regEmail.test(value)) {
        cb()
      } else {
        cb(new Error('邮箱输入错误'))
      }
    }

    // 定义手机号的验证规则 验证手机号是否合法
    const checkMobile = (rule, value, cb) => {
      // 验证手机正则
      const regMobile = /^[1][3,4,5,7,8][0-9]{9}$/
      // 验收手机号的合法性
      if (regMobile.test(value)) {
        cb()
      } else {
        cb(new Error('手机号输入错误'))
      }
    }

    return {
      // 用户列表请求参数
      queryInfo: {
        // 搜索内容
        query: '',
        // 当前页
        pagenum: 1,
        // 页容量
        pagesize: 5
      },
      // 总页数，每次接收请求后更新
      total: 0,
      // 要渲染的用户列表
      userList: [],

      // 用户验证规则
      UserRules: {
        username: [{
          required: true,
          message: '请输入用户名',
          trigger: 'blur'
        },
        {
          min: 3,
          max: 5,
          message: '长度在 3 到 5 个字符',
          trigger: 'blur'
        }],
        password: [{
          required: true,
          message: '请输入密码',
          trigger: 'blur'
        },
        {
          min: 6,
          max: 15,
          message: '长度在 6 到 15 个字符',
          trigger: 'blur'
        }],
        email: [{
          required: true,
          message: '请输入邮箱',
          trigger: 'blur'
        },
        {
          validator: checkEmail,
          trigger: 'blur'
        }],
        mobile: [{
          required: true,
          message: '请输入手机号',
          trigger: 'blur'
        },
        {
          validator: checkMobile,
          trigger: 'blur'
        }]
      },
      // 控制添加用户对话框是否显示
      isAddDialogShow: false,
      // 添加用户
      // 添加表单用到的用户信息
      addUserInfo: {},

      // 控制修改用户对话框的显示颖仓
      isChangeDialogShow: false,
      // 要修改的用户信息
      changeUserInfo: {},

      // 控制修改用户角色弹出框的显示
      isShowEditRoleDialogVisible: false,
      // 编辑角色时的用户信息
      onEditUserRoleInfo: '',
      // 角色信息
      roleInfo: [],
      // 将要修改的用户角色
      updateRole: ''
    }
  },

  methods: {
    // 从后端获取用户列表
    async getUsers() {
      // 发送请求，接收数据
      const {
        data: {
          data,
          meta
        }
      } = await this.$http.get('users', {
        params: this.queryInfo
      })
      // 判断后端返回的状态
      if (meta.status !== 200) return this.$message.error('用户获取失败')
      // 更新用户列表和总页数
      this.userList = data.users
      this.total = data.total
    },

    // 页容量变化触发
    pageSizeChange(e) {
      // 更新容量
      this.queryInfo.pagesize = e
      // 获取新数据
      this.getUsers()
    },

    // 页码变化
    pageCurrentChange(e) {
      // 更新页码
      this.queryInfo.pagenum = e
      // 更新用户列表
      this.getUsers()
    },

    // 修改用户账户状态
    async userStausChange(userInfo) {
      const {
        data: result
      } = await this.$http.put('users/' + userInfo.id + '/state/' + userInfo.mg_state)
      console.log(userInfo, result)
      if (result.meta.status === 200) {
        this.$message.success(userInfo.username + '用户状态修改成功')
      } else {
        this.$message.error(userInfo.username + '用户状态修改失败')
        // this.userList[0]
        userInfo.mg_state = !userInfo.mg_state
      }
    },

    // 重置添加用户的表单
    resetAddFrom() {
      this.$refs.addUserRulesRef.resetFields()
    },

    // 添加用户，发送请求
    addUser() {
      // 二次验证表单规则并获取验证结果
      this.$refs.addUserRulesRef.validate(async val => {
        if (val) {
        // 验证通过执行
          const { data: { data, meta } } = await this.$http.post('users', this.addUserInfo)
          console.log(data)
          if (meta.status === 201) {
            this.$message.success('用户添加成功')
            // 添加成功，隐藏表单
            this.isAddDialogShow = false
            this.getUsers()
          } else {
            // 添加失败，将后端返回的信息提示给用户
            this.$message.error(meta.msg)
          }
        } else {
          this.$message.error('请填写正确的表单内容')
        }
      })
    },

    // 弹出修改用户对话框
    async showChangeUserDialog(uid) {
      // 从服务器查询用户信息
      const { data: { data, meta } } = await this.$http.get('users/' + uid)
      // 判断服务器的响应信息
      if (meta.status === 200) {
        this.changeUserInfo = data
        this.isChangeDialogShow = true
      } else {
        this.$message.error('用户信息获取失败')
      }
    },

    // 重置修改表单
    resetChangeFrom() {
      this.$refs.changeUserRef.resetFields()
    },

    // 修改用户信息
    changeUser(uid) {
      this.$refs.changeUserRef.validate(async val => {
        if (val) {
          // 减少网络传输内容，结构必要字段
          const { email, mobile } = this.changeUserInfo
          // 发送修改请求
          const { data: { meta } } = await this.$http.put('users/' + uid, { email, mobile })
          if (meta.status === 200) {
            this.$message.success('用户修改成功')
            // 隐藏表单
            this.isChangeDialogShow = false
            // 更新数据
            this.getUsers()
          } else {
            // 服务器返回的失败
            this.$message.error('用户修改失败')
          }
        } else {
          // 表单验证失败
          this.$message.error('表单验证失败')
        }
      })
    },

    // 删除用户信息
    async delectUser(uid) {
      // 信息盒子弹出框
      const rult = await this.$confirm('此操作将永久删除该用户, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
        // 捕获错误信息
      }).catch(e => e)
      // 点击确认返回字符串 confirm
      // 点击取消返回 cancel
      if (rult === 'confirm') {
        console.log('确认删除')
        const { data: { meta } } = await this.$http.delete('users/' + uid)
        if (meta.status === 200) {
          this.$message.success(meta.msg)
          this.getUsers()
        } else this.$message.error('删除失败')
      } else {
        this.$message.info('删除操作已取消')
      }
    },

    // 弹出修改角色对话框
    async editUserRole(ele) {
      const { data: ref } = await this.$http.get('roles')
      if (ref.meta.status !== 200) return this.$message.error('角色信息获取失败！')
      // 将option 给 roleInfo
      this.roleInfo = ref.data
      // 给对话框赋值
      this.isShowEditRoleDialogVisible = true
      this.onEditUserRoleInfo = ele
    },

    // 修改用户角色
    async updateUserRole() {
      console.log(this.onEditUserRoleInfo.username)
      const { data: ref } = await this.$http.put('users/' + this.onEditUserRoleInfo.id + '/role', { rid: this.updateRole })
      console.log(ref)
      if (ref.meta.status !== 200) return this.$message.error('角色修改失败！')

      this.$message.success('角色修改成功！')
      this.getUsers()
      this.isShowEditRoleDialogVisible = false
    },

    // 关闭修改角色对话框，重置内容
    closeEditRoleDialog() {
      this.roleInfo = []
      this.updateRole = ''
      this.onEditUserRoleInfo = ''
    }
  },

  created() {
    // 获取用户数据
    this.getUsers()
  }
}
</script>
